using Config;
using Data;
using Entity.Player;
using Entity.Player.State;
using MoonFramework.FSM;
using MoonFramework.Scripts.Event;
using MoonFramework.Template;
using MoonFramework.Test;
using Tool;
using Tool.Name;
using UnityEngine;
using Weapon;

namespace Entity
{
    /// <summary>
    ///  角色模板
    /// </summary>
    public abstract class Character : Actor
    {
        public PlayerData playerData { get; protected set; } //玩家数据
        public PlayerConfig PlayerConfig => (PlayerConfig)ActorConfig; //玩家配置
        public WeaponController WeaponController { get; protected set; } //武器控制器
        public Transform WeaponPoint; //武器挂点
        
        public override void Init(EntityData data, ActorViewController viewController)
        {
            base.Init(data, viewController);
            viewController.tag = "Character";
            WeaponPoint = ((PlayerViewController)viewController).WeaponPoint;
            WeaponController = new WeaponController();
            playerData = ArchiveManager.Instance.PlayerData;
            RegisterEvent();
            SendEvent();
        }

        #region 任务驱动
        protected virtual void RegisterEvent()
        {
            EventCenter.Instance.Register<float>(EventName.RecoverHp);
            EventCenter.Instance.Register<float>(EventName.RecoverHunger);
            EventCenter.Instance.Register<ItemData>(EventName.UpdateWeapon);
        }

        protected virtual void SendEvent()
        {
            EventCenter.Instance.SendCommand<float>(EventName.RecoverHp, OnRecoverHp);
            EventCenter.Instance.SendCommand<float>(EventName.RecoverHunger, OnRecoverHunger);
            EventCenter.Instance.SendCommand<ItemData>(EventName.UpdateWeapon, OnUpdateWeapon);
        }

        protected virtual void RemoveEvent()
        {
            EventCenter.Instance.RemoveCommand<float>(EventName.RecoverHp, OnRecoverHp);
            EventCenter.Instance.RemoveCommand<float>(EventName.RecoverHunger, OnRecoverHunger);
            EventCenter.Instance.RemoveCommand<ItemData>(EventName.UpdateWeapon, OnUpdateWeapon);
        }
        #endregion

        #region 生命，饥饿   
        protected void OnStateDown()
        {
            if (playerData.Hunger > 0)
            {
                playerData.Hunger -= Time.deltaTime * PlayerConfig.HungerDownSpeed;
                playerData.Hunger = Mathf.Max(0, playerData.Hunger);
                EventCenter.Instance.Callback<float>(EventName.UpdateHunger, playerData.Hunger);
            }
            else
            {
                playerData.Hp -= Time.deltaTime * PlayerConfig.HpDownSpeed;
                playerData.Hp = Mathf.Max(0, playerData.Hp); 
                EventCenter.Instance.Callback<float>(EventName.UpdateHp, playerData.Hp);
                if (playerData.Hp == 0)
                    fsmMachine.ChangeState(nameof(PlayerDeadState));
            }
        }

        private void OnRecoverHp(float value)
        {
            playerData.Hp += value;
            playerData.Hp = Mathf.Clamp(playerData.Hp, 0, PlayerConfig.MaxHp);
            EventCenter.Instance.Callback<float>(EventName.UpdateHp, playerData.Hp);
        }

        private void OnRecoverHunger(float value)
        {
            playerData.Hunger += value;
            playerData.Hunger = Mathf.Clamp(playerData.Hunger, 0, PlayerConfig.MaxHunger);
            EventCenter.Instance.Callback<float>(EventName.UpdateHunger, playerData.Hunger);
        }
        
        public void Hurt(float attackValue)
        {
            Debug.Log("角色受伤");
            playerData.Hp -= attackValue;
            playerData.Hp = Mathf.Max(0, playerData.Hp);
            EventCenter.Instance.Callback(EventName.UpdateHp, playerData.Hp);
            if(playerData.Hp == 0)return;
            fsmMachine.ChangeState(nameof(HurtState));
        }
        #endregion

        private void OnUpdateWeapon(ItemData weaponData)
        {
            WeaponController.ChangeWeapon(weaponData, this);
        }
    }
}